const teamsProxy = require('../proxy/teams')
const usersProxy = require('../proxy/users')
const managementTagsCtl = require('../controller/management-tags')
const messagesCtl = require('../controller/messages')
const jwt = require('jsonwebtoken')
const generateUserRoles = require('../controller/users').generateUserRoles
const updateUserManagement = require('../controller/users').updateUserManagement

exports.searchTeamByCode = async function(req, res, next) {
  try {
    const code = req.query.teamCode
    const filterString = '-management_tags -members -announcement_tags -evaluations -scholarships -contrasts'
    const team = await teamsProxy.fetchTeamByCode(code).select(filterString)
    if (!team) {
      // pass a not exist team_code
      return res.json({ _id: null })
    }
    const dormitories = team.dormitories.map(dormitory => dormitory.name)
    delete team.dormitories
    const data = {
      ...team._doc,
      dormitories
    }
    res.json(data)
  } catch (err) {
    res.status(500).end()
  }
}

exports.getTeamInfo = async function(req, res, next) {
  const { teamId } = req.params
  if (teamId !== req.user.teamId || !req.user.roles.includes('admin')) {
    return res.status(403).end()
  }
  try {
    const filter = 'name allow_join years team_code classes'
    const team = await teamsProxy.fetchTeamById(teamId).select(filter)
    res.json({ ...team.toObject() })
  } catch (err) {
    next(err)
  }
}

exports.updateTeamInfo = async function(req, res, next) {
  const { teamId } = req.params
  if (teamId !== req.user.teamId || !req.user.roles.includes('admin')) {
    return res.status(403).end()
  }
  try {
    const { years, name, allow_join, classes } = req.body
    const newTeam = await teamsProxy.findOneAndUpdate({ _id: teamId }, { years, name, allow_join, classes }).select('-_id years name allow_join classes')
    res.json({ ...newTeam.toObject() })
  } catch (err) {
    console.log(err.message)
    next(err)
  }
}

// TODO: Inbox mail then pass to enter a team
exports.addMember = async function(req, res, next) {
  try {
    const { teamId, userId } = req.params
    // 防止非用户本身加入某个团队
    if (req.user.userId !== userId) {
      return res.status(403).end()
    }
    const allow = await teamsProxy.allowJoin(teamId)
    // 目前仅支持单团队
    if (!allow) {
      console.log('[JOIN] not allowed')
      return res.status(204).end()
    }
    const team = await teamsProxy.addMemberById(teamId, userId)
    const management_tags = []
    if (req.body.cadre) {
      management_tags.push(team.management_tags[0])
      await managementTagsCtl.addUserById(team.management_tags[0], userId)
    }
    const newTeamRecord = {
      team: teamId,
      management: await managementTagsCtl.calculateManagement(management_tags),
      management_tags
    }
    await usersProxy.updateById(userId, { $push: { teams: newTeamRecord }})
    await usersProxy.updateById(userId, {
      cadre: req.body.cadre,
      class: req.body.class,
      dormitory: req.body.dormitory,
      room: req.body.room,
      qq: req.body.qq,
      wechat: req.body.wechat
    })
    const roles = await generateUserRoles(userId)
    const accessToken = jwt.sign({ userId, roles }, 'SSAS.COM.PRIVATE-KEY', { expiresIn: '10m' })
    res.set({
      'Cache-Control': 'no-store',
      'Pragma': 'no-cache'
    })
    res.cookie('X_SSAS_AccessToken', accessToken, { httpOnly: true })
    res.cookie('jl', teamId)
    res.status(200).json({ team: teamId })
  } catch (err) {
    next(err)
  }
}

exports.createTeam = async function(req, res, next) {
  try {
    // const userId = req.session.token.substr(11)
    const { userId } = req.user
    if (usersProxy.isLonely(userId)) {
      const data = {
        name: req.body.name,
        years: req.body.years || 4,
        classes: req.body.classes,
        dormitories: req.body.dormitories.map(v => ({ name: v, rooms: [] }))
      }
      const team = await teamsProxy.createTeam(data.name, data.years, data.classes, data.dormitories)
      await teamsProxy.findOneAndUpdate({ _id: team.id }, { $push: { members: userId }})
      await usersProxy.becomeAdmin(userId, team.id)
      // res.set({
      //   'X-SSAS-AccessTokenReset': jwt.sign({ userId, roles: ['admin'] }, 'SSAS.COM.PRIVATE-KEY', { expiresIn: '10m' })
      // })
      const accessToken = jwt.sign({ userId, roles: ['admin'] }, 'SSAS.COM.PRIVATE-KEY', { expiresIn: '10m' })
      res.set({
        'Cache-Control': 'no-store',
        'Pragma': 'no-cache'
      })
      res.cookie('X_SSAS_AccessToken', accessToken, { httpOnly: true })
      res.cookie('jl', team.id)
      res.json({ team: team.id })
      messagesCtl.sendTo(userId, {
        title: '开放成员加入，开始组建团队之旅',
        direction: '/management'
      })
    } else {
      res.status(403).end()
    }
  } catch (err) {
    next(err)
  }
}

exports.getAllTags = async function(req, res, next) {
  const { teamId } = req.params
  if (teamId !== req.user.teamId || !req.user.roles.includes('admin')) {
    return res.status(403).end()
  }
  try {
    const data = await teamsProxy.getTagsById(teamId)
    res.json({ tags: data })
  } catch (err) {
    next(err)
  }
}

exports.createTag = async function(req, res, next) {
  const { teamId } = req.params
  if (teamId !== req.user.teamId || !req.user.roles.includes('admin')) {
    return res.status(403).end()
  }
  try {
    const tag = await managementTagsCtl.createTagWithName(req.body.name)
    res.json({ ...tag.toObject() })
    await teamsProxy.addTagById(teamId, tag.id)
  } catch (err) {
    next(err)
  }
}

exports.updateTag = async function(req, res, next) {
  const { teamId, tagId } = req.params
  if (teamId !== req.user.teamId || !req.user.roles.includes('admin')) {
    return res.status(403).end()
  }
  const { newTag } = req.body
  try {
    const data = await managementTagsCtl.updatePowerById(tagId, newTag)
    managementTagsCtl.updateAllMembersManagementInTag(data.toObject()._id)
    res.json({ ...data.toObject() })
  } catch (err) {
    next(err)
  }
}

exports.deleteTag = async function(req, res, next) {
  const { teamId, tagId } = req.params
  if (teamId !== req.user.teamId || !req.user.roles.includes('admin')) {
    return res.status(403).end()
  }
  try {
    const deleted = await managementTagsCtl.removeTagInTeam(teamId, tagId)
    res.json({ deleted })
  } catch (err) {
    next(err)
  }
}

exports.getAllMembers = async(req, res, next) => {
  const { teamId } = req.params
  if (teamId !== req.user.teamId || !req.user.roles.includes('admin')) {
    return res.status(403).end()
  }
  try {
    let { page, per_page } = req.query
    if (!page || page < 1) page = 1
    if (!per_page || per_page < 1) per_page = 1
    const items = await teamsProxy.getMembersInTeam(teamId, (page - 1) * per_page, per_page * 1)
    for (const item of items) {
      item._doc.tags = item.teams[0].management_tags
      item._doc.avatar = new Buffer(item._doc.avatar, 'binary').toString('base64')
      delete item._doc.teams
    }
    const team = await teamsProxy.fetchTeamById(teamId)
    res.json({ items, total: team.members.length })
  } catch (err) {
    next(err)
  }
}

exports.addTagToSb = async function(req, res, next) {
  const { teamId, userId, tagId } = req.params
  if (teamId !== req.user.teamId || !req.user.roles.includes('admin')) {
    return res.status(403).end()
  }
  try {
    await usersProxy.addTagToSbInTeam(tagId, userId, teamId)
    await managementTagsCtl.addUserById(tagId, userId)
    res.sendStatus(200)
    await updateUserManagement(userId, teamId)
    console.log(`[AC Update]OK`)
  } catch (err) {
    next(err)
  }
}

exports.removeTagFromSb = async function(req, res, next) {
  const { teamId, userId, tagId } = req.params
  if (teamId !== req.user.teamId || !req.user.roles.includes('admin')) {
    return res.status(403).end()
  }
  try {
    const user = await usersProxy.removeTagFromSbInTeam(tagId, userId, teamId)
    await managementTagsCtl.removeUserById(tagId, userId)
    res.json({ tags: user.teams[0].management_tags })
    await updateUserManagement(userId, teamId)
    console.log(`[AC Update]OK`)
  } catch (err) {
    next(err)
  }
}
